home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / os2 / elvis172.zip / osk.c < prev    next >
C/C++ Source or Header  |  1993-01-06  |  10KB  |  479 lines

  1. /* osk.c */
  2.  
  3. /* ------------------------------------------------------------------- *
  4.  |
  5.  | OS9Lib:  stat(), fstat()
  6.  |
  7.  |
  8.  |     Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
  9.  |                           Ulli Dessauer, Germering and
  10.  |                           Reimer Mellin, Muenchen
  11.  |                           (W-Germany)
  12.  |
  13.  |  This  programm can  be  copied and  distributed freely  for any
  14.  |  non-commercial  purposes.   It can only  be  incorporated  into
  15.  |  commercial software with the written permission of the authors.
  16.  |
  17.  |  If you should modify this program, the authors would appreciate
  18.  |  a notice about the changes. Please send a (context) diff or the
  19.  |  complete source to:
  20.  |
  21.  |  address:     Wolfgang Ocker
  22.  |               Lochhauserstrasse 35a
  23.  |               D-8039 Puchheim
  24.  |               West Germany
  25.  |
  26.  |  e-mail:      weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
  27.  |               pyramid!tmpmbx!recco!weo
  28.  |               pyramid!tmpmbx!nitmar!ud
  29.  |               pyramid!tmpmbx!ramsys!ram
  30.  |
  31.  * ----------------------------------------------------------------- */
  32.  
  33. #ifdef OSK
  34.  
  35. #define PATCHLEVEL 1
  36.  
  37. #include <module.h>
  38. #include <sgstat.h>
  39. #include <sg_codes.h>
  40. #include <direct.h>
  41. #ifndef ELVPRSV
  42. #include <stdio.h>
  43. #include <errno.h>
  44. #include <modes.h>
  45. #include <signal.h>
  46. #include "config.h"
  47. #endif
  48. #include "osk.h"
  49.  
  50. #define TIME(secs) (((secs << 8) / 10) | 0x80000000)
  51.  
  52. /*
  53.  * f s t a t
  54.  */
  55. int fstat(fd, buff)
  56.   int         fd;
  57.   struct stat *buff;
  58. {
  59.   struct fildes ftmp;
  60.   struct tm     ttmp;
  61.   struct _sgr   fopt;
  62.  
  63.   if (_gs_gfd(fd, &ftmp, 16) < 0) /* 16 insteat of sizeof(struct fildes)   */
  64.     return(-1);                   /* used due to a bug in stupid os9net */
  65.  
  66.   if (_gs_opt(fd, &fopt) < 0)
  67.     return(-1);
  68.  
  69.   ttmp.tm_year  = (int) ftmp.fd_date[0];
  70.   ttmp.tm_mon   = (int) ftmp.fd_date[1] - 1;
  71.   ttmp.tm_mday  = (int) ftmp.fd_date[2];    
  72.   ttmp.tm_hour  = (int) ftmp.fd_date[3];
  73.   ttmp.tm_min   = (int) ftmp.fd_date[4];
  74.   ttmp.tm_sec   = 0;
  75.   ttmp.tm_isdst = -1;
  76.  
  77.   buff->st_atime = buff->st_mtime = mktime(&ttmp);
  78.  
  79.   ttmp.tm_year  = (int) ftmp.fd_dcr[0];
  80.   ttmp.tm_mon   = (int) ftmp.fd_dcr[1] - 1;
  81.   ttmp.tm_mday  = (int) ftmp.fd_dcr[2];    
  82.   ttmp.tm_hour  = ttmp.tm_min = ttmp.tm_sec = 0;
  83.   ttmp.tm_isdst = -1;
  84.   
  85.   buff->st_ctime = mktime(&ttmp);
  86.  
  87.   memcpy(&(buff->st_size), ftmp.fd_fsize, sizeof(long));  /* misalignment! */
  88.   buff->st_uid   = ftmp.fd_own[1];
  89.   buff->st_gid   = ftmp.fd_own[0];
  90.   buff->st_mode  = ftmp.fd_att;
  91.   buff->st_nlink = ftmp.fd_link;
  92.  
  93.   buff->st_ino   = fopt._sgr_fdpsn;
  94.   buff->st_dev   = fopt._sgr_dvt;
  95.  
  96.   return(0);
  97. }
  98.  
  99. /*
  100.  * s t a t
  101.  */    
  102. int stat(filename, buff)
  103.   char        *filename;
  104.   struct stat *buff;
  105. {
  106.   register int i, ret;
  107.  
  108.   if ((i = open(filename, S_IREAD)) < 0)
  109.     if ((i = open(filename, S_IFDIR | S_IREAD)) < 0)
  110.       return(-1);
  111.  
  112.   ret = fstat(i, buff);
  113.   close(i);
  114.  
  115.   return(ret);
  116. }
  117.  
  118. /*
  119.     unix library functions mist in OSK
  120.     Author: Peter Reinig
  121. */
  122.  
  123.  
  124. typedef (*procref)();
  125. #define MAX_SIGNAL 10
  126.  
  127. extern exit();
  128.  
  129. static int (*sig_table[MAX_SIGNAL])();
  130. static int _sig_install = 0;
  131.  
  132. sig_handler(sig)
  133. int sig;
  134. {
  135.     if ((int) sig_table[sig] > MAX_SIGNAL)
  136.         sig_table[sig](sig);
  137. }
  138.  
  139. procref signal(sig,func)
  140. int sig;
  141. int (*func)();
  142. {
  143.     int i, (*sav)();
  144.  
  145.     if (!_sig_install) {
  146.         for (i=0; i < MAX_SIGNAL; i++)
  147.             sig_table[i] = exit;
  148.         _sig_install = 1;
  149.         intercept(sig_handler);
  150.     }    
  151.     sav = sig_table[sig];
  152.     switch ((int) func) {
  153.         case SIG_DFL : sig_table[sig] = exit;
  154.                        break;
  155.         case SIG_IGN : sig_table[sig] = 0;
  156.                        break;
  157.         default      : sig_table[sig] = func;
  158.                        break;
  159.     }
  160.     return sav;
  161. }
  162.  
  163. perror(str)
  164. char *str;
  165. {
  166.     static int path = 0;
  167.     if (!path && (path = open("/dd/sys/Errmsg", S_IREAD)) == -1) {
  168.         fprintf(stderr,"Can\'t open error message file\n");
  169.         path = 0;
  170.     }
  171.     if (str && *str) {
  172.         fprintf(stderr,"%s: ",str);
  173.         fflush(stderr);
  174.     }
  175.     prerr(path,(short) errno);
  176. }
  177.  
  178. isatty(fd)
  179. int fd;
  180. {
  181.     struct sgbuf buffer;
  182.     char type;
  183.  
  184.     _gs_opt(fd,&buffer);
  185.     type = buffer.sg_class;
  186.     if (type == DT_SCF)
  187.         return 1;
  188.     else
  189.         return 0;
  190. }
  191.  
  192. static struct passwd pw;
  193. static char line[128];
  194.  
  195. struct passwd *getpwuid(uid)
  196. int uid;
  197. {
  198.     FILE   *fp;
  199.     register char *p, *q;
  200.  
  201.     if ((fp = fopen(PASSWD, "r")) == NULL)
  202.         return (struct passwd *) NULL;
  203.     while (fgets(line, sizeof(line), fp)) {
  204.         p = q = line;
  205.         while (*p && *p != ',') p++;
  206.         if (!*p)
  207.             continue;
  208.         *p = '\0';
  209.         pw.pw_name = q;
  210.         q = ++p;
  211.         while (*p && *p != ',') p++;
  212.         if (!*p)
  213.             continue;
  214.         *p = '\0';
  215.         pw.pw_passwd = q;
  216.         q = ++p;
  217.         while (*p && *p != '.') p++;
  218.         if (!*p)
  219.             continue;
  220.         *p = '\0';
  221.         pw.pw_gid = atoi(q);
  222.         q = ++p;
  223.         while (*p && *p != ',') p++;
  224.         if (!*p)
  225.             continue;
  226.         *p = '\0';
  227.         pw.pw_uid = atoi(q);
  228.         q = ++p;
  229.         if (uid != pw.pw_uid)
  230.             continue;
  231.         while (*p && *p != ',') p++;
  232.         if (!*p)
  233.             return (struct passwd *) NULL;
  234.         *p = '\0';
  235.         pw.pw_prio = atoi(q);
  236.         q = ++p;
  237.         while (*p && *p != ',') p++;
  238.         if (!*p)
  239.             return (struct passwd *) NULL;
  240.         *p = '\0';
  241.         pw.pw_xdir = q;
  242.         q = ++p;
  243.         while (*p && *p != ',') p++;
  244.         if (!*p)
  245.             return (struct passwd *) NULL;
  246.         *p = '\0';
  247.         pw.pw_dir = q;
  248.         p++;
  249.         if (!*p)
  250.             return (struct passwd *) NULL;
  251.         pw.pw_shell = p;
  252.         while (*p++) ;
  253.         *(--p) = '\0';
  254.         return &pw;
  255.     }
  256.     return (struct passwd *) NULL;
  257. }
  258.  
  259. /* This function is used to catch the alarm signal */
  260. static int dummy()
  261. {
  262. }
  263.  
  264. /* This function implements read-with-timeout from the keyboard.*/
  265. int ttyread(buf, len, time)
  266.     char    *buf;    /* where to store the gotten characters */
  267.     int    len;    /* maximum number of characters to read */
  268.     int    time;    /* maximum time to allow for reading characters */
  269. {
  270.     REG int    i;
  271.     int    alrmid;
  272.  
  273.     /* are some characters available in the type-ahead buffer? */
  274.     if ((i = _gs_rdy(0)) > 0)
  275.     {
  276.         /* some characters are available -- read them immediately */
  277.         len = read(0, buf, i < len ? i : len);
  278.     }
  279.     else if (!time) /* reading with no timeout? */
  280.     {
  281.         /* do a blocking read, with no timeout */
  282.         do
  283.             len = read(0, buf, 1);
  284.         while (len < 0);
  285.     }
  286.     else
  287.     {
  288.         /* set an alarm and then do a blocking read */
  289.         signal(SIGQUIT, dummy);
  290.         alrmid = alm_set(SIGQUIT, TIME(time));
  291.         len =  read(0, buf, 1);
  292.         alm_delete(alrmid);
  293.     }
  294.     return len;
  295. }
  296.  
  297. /* The code of getcwd, popen and pclose is taken from blarslib from Bob Larson */
  298.  
  299. /* Internet:    blarson@usc.edu */
  300. /* StG:            blarson@zog */
  301. /* Compuserve:    75126.723@compuserve.com */
  302.  
  303. char *getcwd(p, n)
  304. char *p;
  305. int n;
  306. {
  307.     register char *cp;
  308.     register struct dirent *dp;
  309.     register int l, olddot = 0, i, d, dot, dotdot;
  310.     struct dirent db[8];
  311.     char buf[1024];
  312.  
  313.     if(p==NULL) {
  314.         p = (char *)malloc((unsigned)n);
  315.         if(p==NULL) return NULL;
  316.     }
  317.     cp = &buf[1024-1];
  318.     *cp = '\0';
  319.     for(;;) {
  320.         if((d = open(".", S_IREAD | S_IFDIR)) < 0) {
  321.             if(*cp) chdir(cp+1);
  322.             return NULL;
  323.         }
  324.         if((i = read(d, (char *)db, sizeof(db))) == 0) {
  325.             if(*cp) chdir(cp+1);
  326.             close(d);
  327.             return NULL;
  328.         }
  329.         dotdot = db[0].dir_addr;
  330.         dot = db[1].dir_addr;
  331.         if(olddot) {
  332.             i -= 2 * sizeof(struct dirent);
  333.             dp = &db[2];
  334.             for(;;) {
  335.                 if(i <= 0) {
  336.                     if((i = read(d, (char *)db, sizeof(db))) == 0) {
  337.                     if(*cp) chdir(cp+1);
  338.                     close(d);
  339.                     return NULL;
  340.                 }
  341.             dp = &db[0];
  342.             }
  343.             if(olddot == dp->dir_addr) {
  344.                 l = strlen(dp->dir_name);
  345.                 /* last character has parity bit set... */
  346.                 *--cp = dp->dir_name[--l] & 0x7f;
  347.                 while(l) *--cp = dp->dir_name[--l];
  348.                 *--cp = '/';
  349.                 break;
  350.             }
  351.             i -= sizeof(struct dirent);
  352.             dp++;
  353.             }
  354.         }
  355.         if(dot==dotdot) {
  356.             if(*cp) chdir(cp+1);
  357.             *p = '/';
  358.             if(_gs_devn(d, p+1) < 0) {
  359.                 close(d);
  360.                 return NULL;
  361.             }
  362.             close(d);
  363.             if(n < (strlen(p) + strlen(cp))) return NULL;
  364.             strcat(p, cp);
  365.             return p;
  366.         }
  367.         close(d);
  368.         if(chdir("..") != 0) {
  369.             if(*cp) chdir(cp+1);
  370.             return NULL;
  371.         }
  372.         olddot = dot;
  373.     }
  374. }
  375.  
  376. extern char *environ;
  377. extern int os9forkc();
  378.  
  379. static int proc[_NFILE];
  380.  
  381. /* This version of popen is derived from Robert B. Larson library blarslib *
  382. /* and was modified by Peter Reinig to meet the needs of elvis */
  383.  
  384. FILE *popen(command, mode)
  385. char *command;
  386. char *mode;
  387. {
  388.     int pipe;
  389.  
  390.     if (pipe = osk_popen(command, mode, 0, 1))
  391.         return (fdopen(pipe, mode));
  392.     else
  393.         return ((FILE*) NULL);
  394. }
  395.  
  396. mod_exec *mp = -1;
  397.  
  398. int osk_popen(command, mode, in, as_popen)
  399. char *command;
  400. char *mode;
  401. int in, as_popen;
  402. {
  403.     int temp, fd, stdinp;
  404.     int pipe, pid;
  405.     char *argv[4];
  406.     register char *cp;
  407.     static char namebuffer[128];
  408.     static char module[128];
  409.  
  410.     if(mode[1]!='\0' || (*mode!='r' && *mode!='w'))
  411.         return 0;
  412.     fd = (*mode=='r');
  413.     if((temp = dup(fd)) <= 0)
  414.         return 0;
  415.     if((pipe = creat("/pipe", S_IREAD | S_IWRITE)) < 0) {
  416.         close(temp);
  417.         return 0;
  418.     }
  419.     close(fd);
  420.     dup(pipe);
  421.     if (in != 0) {
  422.         stdinp = dup(0);
  423.         close(0);
  424.         dup(in);
  425.         close(in);
  426.     }
  427.     argv[0] = "shell";
  428.     argv[1] = "ex";
  429.     argv[2] = command;
  430.     argv[3] = (char *)NULL;
  431.     strcpy(module, command);
  432.     cp = module;
  433.     while (*cp && *cp != ' ' && *cp != '\t') cp++;
  434.     *cp = '\0';
  435.     mp = (mod_exec *)modloadp(module, (MT_PROGRAM << 8) + ML_ANY, namebuffer);
  436.     if((mp == (mod_exec*)-1)
  437.         || ((pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3)) < 0)) {
  438.         if (mp > 0)
  439.             munlink(mp);
  440.         mp = (mod_exec *) -1;
  441.         close(fd);
  442.         close(pipe);
  443.         dup(temp);
  444.         close(temp);
  445.         if (in != 0) {
  446.             close(0);
  447.             dup(stdinp);
  448.         }
  449.         return 0;
  450.     }
  451.     if (as_popen)
  452.         proc[pipe] = pid;
  453.     close(fd);
  454.     dup(temp);
  455.     close(temp);
  456.     if (in != 0) {
  457.         close(0);
  458.         dup(stdinp);
  459.     }
  460.     return pipe;
  461. }
  462.  
  463. int pclose(pipe)
  464. FILE *pipe;
  465. {
  466.     int p, stat, w;
  467.  
  468.     if((p = proc[fileno(pipe)]) <= 0) return -1;
  469.     proc[fileno(pipe)] = 0;
  470.     fflush(pipe);
  471.     fclose(pipe);
  472.     while((w = wait(&stat)) != -1 && w != p) ;
  473.     if (mp > 0)
  474.         munlink(mp);
  475.     mp = (mod_exec *) -1;
  476.     return w == -1 ? -1 : stat;
  477. }
  478. #endif /* OSK */
  479.